home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWPart / Sources / FWInter.cpp < prev    next >
Encoding:
Text File  |  1996-04-25  |  14.2 KB  |  484 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWInter.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWINTER_H
  13. #include "FWInter.h"
  14. #endif
  15.  
  16. #ifndef FWPART_H
  17. #include "FWPart.h"
  18. #endif
  19.  
  20. #ifndef FWPRMISE_H
  21. #include "FWPrmise.h"
  22. #endif
  23.  
  24. #ifndef FWCLNINF_H
  25. #include "FWClnInf.h"
  26. #endif
  27.  
  28. #ifndef FWBARRAY_H
  29. #include "FWBArray.h"
  30. #endif
  31.  
  32. #ifndef FWFRAME_H
  33. #include "FWFrame.h"
  34. #endif
  35.  
  36. #ifndef FWUTIL_H
  37. #include "FWUtil.h"
  38. #endif
  39.  
  40. #ifndef FWCONTNT_H
  41. #include "FWContnt.h"
  42. #endif
  43.  
  44. #ifndef FWPRMISE_H
  45. #include "FWPrmise.h"
  46. #endif
  47.  
  48. #ifndef FWLNKSRC_H
  49. #include "FWLnkSrc.h"
  50. #endif
  51.  
  52. // ----- OpenDoc Includes -----
  53.  
  54. #ifndef SOM_ODStorageUnit_xh
  55. #include <StorageU.xh>
  56. #endif
  57.  
  58. #ifndef SOM_ODSession_xh
  59. #include <ODSessn.xh>
  60. #endif
  61.  
  62. #ifndef SOM_ODClipboard_xh
  63. #include <Clipbd.xh>
  64. #endif
  65.  
  66. #ifndef SOM_ODStorageUnitView_xh
  67. #include <SUView.xh>
  68. #endif
  69.  
  70. #ifndef SOM_ODFacet_xh
  71. #include <Facet.xh>
  72. #endif
  73.  
  74. #ifndef SOM_Module_OpenDoc_StdProps_defined
  75. #include <StdProps.xh>
  76. #endif
  77.  
  78. //========================================================================================
  79. // RunTime Info
  80. //========================================================================================
  81.  
  82. #ifdef FW_BUILD_MAC
  83. #pragma segment FWFrameworkContent
  84. #endif
  85.  
  86. //========================================================================================
  87. //    class FW_CDataInterchange
  88. //========================================================================================
  89.  
  90. //----------------------------------------------------------------------------------------
  91. //    FW_CDataInterchange constructor
  92. //----------------------------------------------------------------------------------------
  93.  
  94. FW_CDataInterchange::FW_CDataInterchange(Environment* ev, FW_CPart* part) :
  95.     fPart(part),
  96.     fLinkPromises(NULL),
  97.     fClipboardPromise(NULL),
  98.     fDragAndDropPromise(NULL)
  99. {
  100. FW_UNUSED(ev);
  101. }
  102.  
  103. //----------------------------------------------------------------------------------------
  104. //    FW_CDataInterchange destructor
  105. //----------------------------------------------------------------------------------------
  106.  
  107. FW_CDataInterchange::~FW_CDataInterchange()
  108. {
  109.     FW_ASSERT(fLinkPromises == NULL);        // Should be NULL by now
  110.     FW_ASSERT(fClipboardPromise == NULL);    // Should be NULL by now
  111.     FW_ASSERT(fDragAndDropPromise == NULL);    // Should be NULL by now
  112. }
  113.  
  114. //---------------------------------------------------------------------------------------
  115. //    FW_CDataInterchange::ExternalizeData
  116. //---------------------------------------------------------------------------------------
  117. //    Note: Even if I am not an embedding part I still need to call BeginClone/EndClone
  118. //    otherwise OpenDoc's OriginalCloneKind property in the draft is not set correctly
  119.  
  120. void FW_CDataInterchange::ExternalizeData(Environment* ev, 
  121.                                           FW_CContent* content,
  122.                                          FW_CFrame* scopeFrame,
  123.                                           ODStorageUnit* destinationSU, 
  124.                                           FW_EStorageKinds storageKind, 
  125.                                           ODCloneKind cloneKind)
  126. {
  127.     if (content == NULL)
  128.         return;
  129.         
  130.     ODDraft* fromDraft = fPart->GetDraft(ev);
  131.     ODDraft* dstDraft = destinationSU->GetDraft(ev);
  132.  
  133.     FW_CCloneInfo cloneInfo(ev, fromDraft, scopeFrame, cloneKind);
  134.     
  135.     cloneInfo.BeginClone(ev, dstDraft);            
  136.     
  137.     PrivHandleExternalizeData(ev, content, destinationSU, storageKind, &cloneInfo);
  138.  
  139.     cloneInfo.EndClone(ev);
  140. }
  141.     
  142. //----------------------------------------------------------------------------------------
  143. //    FW_CDataInterchange::PrivHandleExternalizeData
  144. //----------------------------------------------------------------------------------------
  145.  
  146. void FW_CDataInterchange::PrivHandleExternalizeData(Environment* ev,
  147.                                                       FW_CContent* content,
  148.                                                     ODStorageUnit* destinationSU, 
  149.                                                     FW_EStorageKinds storageKind,
  150.                                                     FW_CCloneInfo* cloneInfo)
  151. {
  152.     if (storageKind == FW_kClipboardStorage || storageKind == FW_kDragAndDropStorage)
  153.         PrivDeletePromises(ev, storageKind);
  154.  
  155.     // ----- Add the needed properties first -----
  156.     fPart->AddProperties(ev, destinationSU);
  157.     
  158.     content->Externalize(ev, destinationSU, storageKind, cloneInfo);
  159.  
  160.     // ----- If supported, write a shape property -----
  161.     FW_CAcquiredODShape aqSelectionShape = content->CreateDataFrameShape(ev);
  162.     if (((ODShape*)aqSelectionShape) != NULL)
  163.     {
  164.         // ----- Add the property. WriteShape will add the value
  165.         if (destinationSU->Exists(ev, kODPropFrameShape, (ODValueType)NULL, 0))
  166.         {
  167.             destinationSU->Focus(ev, kODPropFrameShape, 
  168.                                 kODPosUndefined, 
  169.                                    (ODValueType)NULL, 
  170.                                 (ODValueIndex)1, 
  171.                                 kODPosUndefined);
  172.             destinationSU->Remove(ev);                // remove the first value
  173.         }
  174.         else
  175.             destinationSU->AddProperty(ev, kODPropFrameShape);
  176.             
  177.         aqSelectionShape->WriteShape(ev, destinationSU);
  178.     }
  179. }
  180.  
  181. //---------------------------------------------------------------------------------------
  182. //    FW_CDataInterchange::InternalizeData
  183. //---------------------------------------------------------------------------------------
  184. //    Note: Even if I am not an embedding part I still need to call BeginClone/EndClone
  185. //    otherwise OpenDoc's OriginalCloneKind property in the draft is not set correctly
  186.  
  187. FW_EInternalizeResult FW_CDataInterchange::InternalizeData(Environment* ev, 
  188.                                                             FW_CContent* content,
  189.                                                             FW_CFrame* scopeFrame,
  190.                                                             ODStorageUnit* sourceSU,
  191.                                                             FW_EStorageKinds storageKind, 
  192.                                                             ODCloneKind cloneKind,
  193.                                                             ODPasteAsResult* embedAsInfo)
  194. {
  195.     ODDraft* fromDraft = sourceSU->GetDraft(ev);
  196.     ODDraft* dstDraft = fPart->GetDraft(ev);
  197.  
  198.     FW_EInternalizeResult result = FW_kInternalizeFailed;
  199.  
  200.     FW_CCloneInfo cloneInfo(ev, fromDraft, scopeFrame, cloneKind);
  201.     
  202.     if (embedAsInfo && embedAsInfo->mergeSetting == kODFalse)
  203.     {
  204.         result = PrivHandleEmbedAs(ev, content, sourceSU, &cloneInfo, embedAsInfo);
  205.     }
  206.     else
  207.     {
  208.         cloneInfo.BeginClone(ev, dstDraft);
  209.  
  210.         result = PrivHandleInternalizeData(ev, content, sourceSU, storageKind, &cloneInfo);        
  211.  
  212.         if (result == FW_kInternalizeFailed) 
  213.         {
  214.             cloneInfo.AbortClone(ev);
  215.             return result;
  216.         }
  217.  
  218.         cloneInfo.EndClone(ev);
  219.  
  220.         PrivPostInternalizeData(ev, content, &cloneInfo, result);
  221.     }
  222.     
  223.     return result;
  224. }
  225.     
  226. //----------------------------------------------------------------------------------------
  227. //    FW_CDataInterchange::PrivPostInternalizeData
  228. //----------------------------------------------------------------------------------------
  229.  
  230. void FW_CDataInterchange::PrivPostInternalizeData(Environment* ev, 
  231.                                                 FW_CContent* content,
  232.                                                   FW_CCloneInfo* cloneInfo, 
  233.                                                   FW_EInternalizeResult result)
  234. {
  235. FW_UNUSED(ev);
  236. FW_UNUSED(content);
  237. FW_UNUSED(result);
  238. FW_UNUSED(cloneInfo);
  239.  
  240.     // Nothing to do. See: FW_CEmbeddingDataInterchange::PrivPostInternalizeData
  241. }
  242.  
  243. //----------------------------------------------------------------------------------------
  244. //    FW_CDataInterchange::PrivHandleInternalizeData
  245. //----------------------------------------------------------------------------------------
  246.  
  247. FW_EInternalizeResult FW_CDataInterchange::PrivHandleInternalizeData(Environment* ev, 
  248.                                                                     FW_CContent* content,
  249.                                                                      ODStorageUnit* sourceSU, 
  250.                                                                     FW_EStorageKinds storageKind, 
  251.                                                                      FW_CCloneInfo* cloneInfo)
  252. {
  253.     
  254.     FW_Boolean result = content->Internalize(ev, sourceSU, storageKind, cloneInfo);
  255.     return result ? FW_kInternalizeContent : FW_kInternalizeFailed;
  256. }
  257.  
  258. //----------------------------------------------------------------------------------------
  259. //    FW_CDataInterchange::PrivHandleEmbedAs
  260. //----------------------------------------------------------------------------------------
  261.  
  262. FW_EInternalizeResult FW_CDataInterchange::PrivHandleEmbedAs(Environment* ev, 
  263.                                                             FW_CContent* content,
  264.                                                              ODStorageUnit* sourceSU,
  265.                                                              FW_CCloneInfo* cloneInfo,
  266.                                                              ODPasteAsResult* embedAsInfo)
  267. {
  268. FW_UNUSED(ev);
  269. FW_UNUSED(content);
  270. FW_UNUSED(sourceSU);
  271. FW_UNUSED(cloneInfo);
  272. FW_UNUSED(embedAsInfo);
  273.  
  274.     FW_DEBUG_MESSAGE("FW_CDataInterchange::PrivHandleEmbedAs should never be called");
  275.     return FW_kInternalizeFailed;
  276. }
  277.  
  278. //----------------------------------------------------------------------------------------
  279. // FW_CDataInterchange::ResolveClipboardPromise
  280. //----------------------------------------------------------------------------------------
  281.  
  282. void FW_CDataInterchange::ResolveClipboardPromise(Environment* ev)
  283. {
  284.     if (fClipboardPromise == NULL)
  285.         return;
  286.  
  287.     ODClipboard* clipboard = fPart->GetSession(ev)->GetClipboard(ev);
  288.     ODStorageUnit* clipboardSU = clipboard->GetContentStorageUnit(ev);
  289.     if (clipboard->GetUpdateID(ev) == fClipboardPromise->GetUpdateID(ev))
  290.         clipboardSU->ResolveAllPromises(ev);
  291.     else
  292.         PrivDeletePromises(ev, FW_kClipboardStorage);
  293.         
  294.     FW_ASSERT(fClipboardPromise == NULL);
  295. }
  296.  
  297. //----------------------------------------------------------------------------------------
  298. // FW_CDataInterchange::ResolveAllPromises
  299. //----------------------------------------------------------------------------------------
  300. //    Will resolve all promises (clipboard and all link promises)
  301.  
  302. void FW_CDataInterchange::ResolveAllPromises(Environment* ev)
  303. {
  304.     // ----- I should never have to resolve a drag and drop promise -----
  305.     PrivDeletePromises(ev, FW_kDragAndDropStorage);
  306.  
  307.     // ----- resolve Clipboard promise -----
  308.     ResolveClipboardPromise(ev);
  309.     
  310.     // ----- Resolve link promises -----
  311.     if (fLinkPromises != NULL)
  312.     {
  313.         FW_CPromise* promise = fLinkPromises->First();
  314.         while (promise != NULL)
  315.         {
  316.             FW_CPromise* next = fLinkPromises->After(promise);
  317.             promise->PrivGetLinkSource(ev)->ResolveAllPromises(ev);    // fLinkPromises might get deleted here
  318.             promise = next;
  319.         }
  320.     }
  321.  
  322.     // ----- Should be NULL by now
  323.     FW_ASSERT(fLinkPromises == NULL);        
  324.     FW_ASSERT(fClipboardPromise == NULL);
  325.     FW_ASSERT(fDragAndDropPromise == NULL);
  326. }
  327.  
  328. //---------------------------------------------------------------------------------------
  329. //    FW_CDataInterchange::PrivDeletePromises
  330. //---------------------------------------------------------------------------------------
  331.  
  332. void FW_CDataInterchange::PrivDeletePromises(Environment* ev, FW_EStorageKinds storageKind)
  333. {
  334. FW_UNUSED(ev);
  335.     if (storageKind == FW_kClipboardStorage)
  336.     {
  337.         delete fClipboardPromise;        // Will call PrivPromiseDeleted
  338.         FW_ASSERT(fClipboardPromise == NULL);
  339.     }
  340.     else if (storageKind == FW_kDragAndDropStorage)
  341.     {
  342.         delete fDragAndDropPromise;        // Will call PrivPromiseDeleted
  343.         FW_ASSERT(fDragAndDropPromise == NULL);
  344.     }
  345.     else if (storageKind == FW_kLinkStorage)
  346.     {    
  347.         if (fLinkPromises != NULL)
  348.         {
  349.             FW_CPromise* promise = fLinkPromises->First();
  350.             while (promise != NULL)
  351.             {
  352.                 FW_CPromise* next = fLinkPromises->After(promise);
  353.                 delete promise;            // Will call PrivPromiseDeleted
  354.                 promise = next;
  355.             }
  356.             
  357.             FW_ASSERT(fLinkPromises == NULL);
  358.         }
  359.     }
  360.     else
  361.     {
  362.         FW_DEBUG_MESSAGE("FW_CDataInterchange::ResolveAllPromises - Unknown storageKind");
  363.     }
  364. }
  365.  
  366. //---------------------------------------------------------------------------------------
  367. //    FW_CDataInterchange::PrivDeleteLinkPromises
  368. //---------------------------------------------------------------------------------------
  369.  
  370. void FW_CDataInterchange::PrivDeleteLinkPromises(Environment* ev, FW_CLinkSource* linkSource)
  371. {
  372.     if (fLinkPromises != NULL)
  373.     {    
  374.         FW_TOrderedCollection<FW_CPromise> temp;
  375.         FW_CPromise* promise;                        // %%% sfu
  376.          
  377.         FW_TOrderedCollectionIterator<FW_CPromise> ite(fLinkPromises);
  378.         for (promise = ite.First(); ite.IsNotComplete(); promise = ite.Next())
  379.         {
  380.             if (promise->PrivGetLinkSource(ev) == linkSource)
  381.             {
  382.                 temp.AddLast(promise);
  383.             }
  384.         }
  385.  
  386.         FW_TOrderedCollectionIterator<FW_CPromise> ite2(&temp);
  387.         for (promise = ite2.First(); ite2.IsNotComplete(); promise = ite2.Next())
  388.         {
  389.             delete promise;        // Will call PrivPromiseDeleted
  390.         }
  391.     }
  392. }
  393.  
  394. //----------------------------------------------------------------------------------------
  395. //    FW_CDataInterchange::PrivPromise
  396. //----------------------------------------------------------------------------------------
  397.  
  398. void FW_CDataInterchange::PrivPromise(Environment *ev, 
  399.                                     FW_CPromise* promise,
  400.                                     ODStorageUnit* storageUnit, 
  401.                                     ODPropertyName propertyName, 
  402.                                     ODValueType valueType)
  403. {    
  404.     FW_ASSERT(propertyName != NULL);
  405.     FW_ASSERT(valueType != NULL);
  406.  
  407.     storageUnit->Focus(ev, propertyName, kODPosUndefined, NULL, 0, kODPosUndefined);
  408.  
  409.     FW_CPromise* buffer = promise;
  410.     FW_CByteArray bArray(&buffer, sizeof(FW_CPromise*));
  411.     storageUnit->SetPromiseValue(ev,
  412.                                 valueType,
  413.                                 0,
  414.                                 bArray,
  415.                                 fPart->GetODPart(ev));    
  416.     
  417.     // ----- add the promise -----
  418.     //     Attention that a promise object can be promised multiple time
  419.     
  420.     FW_EStorageKinds storageKind = promise->GetStorageKind(ev);
  421.  
  422.     if (storageKind == FW_kLinkStorage)
  423.     {
  424.         if (fLinkPromises == NULL)
  425.             fLinkPromises = FW_NEW(FW_TOrderedCollection<FW_CPromise>, ());
  426.         
  427.         if (!fLinkPromises->Contains(promise))
  428.             fLinkPromises->AddLast(promise);
  429.     }
  430.     else if (storageKind == FW_kClipboardStorage)
  431.     {
  432.         FW_ASSERT(fClipboardPromise == NULL || fClipboardPromise == promise);
  433.         fClipboardPromise = promise;
  434.     }
  435.     else if (storageKind == FW_kDragAndDropStorage)
  436.     {
  437.         FW_ASSERT(fDragAndDropPromise == NULL || fDragAndDropPromise == promise);
  438.         fDragAndDropPromise = promise;
  439.     }
  440.     else
  441.     {
  442.         FW_DEBUG_MESSAGE("FW_CDataInterchange::ResolveAllPromises - Unknown storageKind");
  443.     }
  444. }
  445.  
  446. //----------------------------------------------------------------------------------------
  447. //    FW_CDataInterchange::PrivPromiseDeleted
  448. //----------------------------------------------------------------------------------------
  449. //    call  by the destructor of FW_CPromise
  450.  
  451. void FW_CDataInterchange::PrivPromiseDeleted(Environment *ev, FW_CPromise* promise)
  452. {
  453.     FW_EStorageKinds storageKind = promise->GetStorageKind(ev);
  454.  
  455.     if (storageKind == FW_kLinkStorage)
  456.     {
  457.         FW_ASSERT(fLinkPromises != NULL);
  458.         FW_ASSERT(fLinkPromises->Contains(promise));
  459.     
  460.         fLinkPromises->Remove(promise);
  461.         
  462.         if (fLinkPromises->Count() == 0)
  463.         {
  464.             delete fLinkPromises;
  465.             fLinkPromises = NULL;
  466.         }
  467.     }
  468.     else if (storageKind == FW_kClipboardStorage)
  469.     {
  470.         FW_ASSERT(fClipboardPromise == promise);
  471.         fClipboardPromise = NULL;
  472.     }
  473.     else if (storageKind == FW_kDragAndDropStorage)
  474.     {
  475.         FW_ASSERT(fDragAndDropPromise == promise);
  476.         fDragAndDropPromise = NULL;
  477.     }
  478.     else
  479.     {
  480.         FW_DEBUG_MESSAGE("FW_CDataInterchange::ResolveAllPromises - Unknown storageKind");
  481.     }
  482. }
  483.  
  484.